﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace Kokomo.Mirror.PeFormat
{
	[Description("DOS Header")]
	public class DosHeader : PeHeaderStruct
	{
		public static readonly ushort MzSignature = 0x5A4D;

		// DOS .EXE header
		[TypeConverter(typeof(HexConverter))]
		public ushort Magic { get; private set; }

		[NonSerializedProperty]
		[DisplayName("Is magic valid?")]
		public bool IsMagicValid { get { return this.Magic == MzSignature; } }

		[DisplayName("Bytes on last page of file")]
		[TypeConverter(typeof(HexConverter))]
		public short BytesOnLastPageOfFile { get; private set; }

		[DisplayName("Pages in file")]
		[PeCategory(PeCategory.Layout)]
		public ushort PagesInFile { get; private set; }

		[DisplayName("Relocations")]
		[PeCategory(PeCategory.Layout)]
		public ushort Relocations { get; private set; }

		[DisplayName("Header size (in paragraphs)")]
		[PeCategory(PeCategory.Layout)]
		public ushort HeaderParagraphs { get; private set; }

		[DisplayName("Minimum extra paragraphs")]
		[PeCategory(PeCategory.Layout)]
		public ushort MinimumExtraParagraphs { get; private set; }

		[DisplayName("Maximum extra paragraphs")]
		[PeCategory(PeCategory.Layout)]
		public ushort MaximumExtraParagraphs { get; private set; }

		[DisplayName("Initial stack segment")]
		[PeCategory(PeCategory.State)]
		public ushort InitialStackSegment { get; private set; }

		[DisplayName("Initial stack pointer")]
		[PeCategory(PeCategory.State)]
		[TypeConverter(typeof(HexConverter))]
		public ushort InitialStackPointer { get; private set; }

		[DisplayName("Checksum")]
		[TypeConverter(typeof(HexConverter))]
		public ushort Checksum { get; private set; }

		[DisplayName("Initial instruction pointer")]
		[PeCategory(PeCategory.State)]
		[TypeConverter(typeof(HexConverter))]
		public ushort InitialInstructionPointer { get; private set; }

		[DisplayName("Initial code segment")]
		[PeCategory(PeCategory.State)]
		[TypeConverter(typeof(HexConverter))]
		public ushort InitialCodeSegment { get; private set; }

		[DisplayName("Relocation table offset")]
		[PeCategory(PeCategory.Layout)]
		[TypeConverter(typeof(HexConverter))]
		public ushort RelocationTableOffset { get; private set; }

		[DisplayName("Overlay number")]
		[TypeConverter(typeof(HexConverter))]
		public short OverlayNumber { get; private set; }

		[SerializedArray(ArrayLengthEncoding.Fixed, 4)]
		[Browsable(false)]
		public short[] Reserved { get; private set; }

		[DisplayName("OEM ID")]
		[TypeConverter(typeof(HexConverter))]
		public ushort OemID { get; private set; }

		[DisplayName("OEM info")]
		[TypeConverter(typeof(HexConverter))]
		public ushort OemInfo { get; private set; }

		[SerializedArray(ArrayLengthEncoding.Fixed, 10)]
		[Browsable(false)]
		public ushort[] MoreReserved { get; private set; }

		[DisplayName("New EXE header offset")]
		[PeCategory(PeCategory.Layout)]
		[TypeConverter(typeof(HexConverter))]
		public uint NewExeHeaderOffset { get; private set; }

		public bool IsValid
		{
			get
			{
				return this.Magic == MzSignature;
			}
		}
	}
}
